﻿<html>
<head>
<!--Baue Datenstruktur mit allen eingefangenen Requests -->
<script type="text/javascript">
    
    var reference_html = null;      //dieses html (server response) soll gegenueber einem anderen per diff verglichen werden, wird in ForgePanel gesetzt
    var requests = [];
    var capture_mode = -1;           // 0 = capture all (standard), 1 = capture only from active tab, -1 = disable capturing
    var filter_str = null;            // enthaelt nach filter query die indizes der resultate in der requests datenstruktur, aufsteigend sortiert, ist sonst leeres array
    var known_sessionid_names = [   // konfigurierbar,erweiterbar machen durch .json datei oder durch zus. eingabefeld
        "JSESSIONID",
        "PHPSESSID",
        "ASPSESSIONID",
        "phpbb2mysql_sid",
    ];
    var user_agent_header = [
        "Origin",
        "User-Agent",
        "Referer",
        "Accept-Encoding",
        "Accept-Charset",
        "Cookie"
    ];
    /******************************************************************************************************************************************
     * requests = Array von Objekten die eine eingefangene Anfrage repraesentieren
     * Struktur post request: { form_number: i, params: param_arr, url: this.action, header: header_arr,method: "post" }
     * Struktur get request: { form_number: i, params: param_arr, url: this.action, header: header_arr,method: "get",type:<webRequest.details.type> }
     *
     * header_arr ist bei n Headern ein array von Objekten der Form [{name:header_name_1, value:header_value_1}, .... , {name:header_name_n, value:hedaer_value_n}]
     * param_arr ist bei n Parameterpaaren ein array von Objekten der Form [{name:name_1, value:value_1}, .... , {name:name_n, value:value_n}]
     * IMPORTANT: parameters sind bereits decodiert im Array, d.h. später kein Aufruf mehr an decodeURIComponent noetig
     ******************************************************************************************************************************************/

    // TODO: 
    //  -Requests bei eingeben eines suchbegriffs bei dict.cc,http://www.webtoolkit.info werden nicht eingefangen
    
    var request_data = null; // Received data from Content Script gets stored here!
    var blocking_mode = false;


    function getParamsFromURL (url) {
        // return GET parameter als array ret_arr = [{name:"name_1",value:"value_1"}, ... , {name:"name_n",value:"value_n"}];
        var ret_arr = [];
        var i = url.indexOf("?");
        if(i == -1 || i==url.length-1) {
            //keine Get Parameter, gebe leeres Array zurueck
            return ret_arr;
        }
        else {
            param_str = url.substring(i + 1);
            ret_arr = getParamsFromSerialize(param_str);
            
            return ret_arr;
        }
    }

    function decodeParamString(encoded_param) {
        return decodeURIComponent(encoded_param.replace(/\+/g, " "));
    }

    function getParamsFromSerialize(serialized_str) {
        // return POST parameter als array ret_arr = [{name:"name_1",value:"value_1"}, ... , {name:"name_n",value:"value_n"}];
        
        var ret_arr = [];

        if (serialized_str == "") {
            return ret_arr;
        }
        //console.log(serialized_str);
        if (serialized_str.length > 2) {
            p_arr = serialized_str.split("&");
            var i;
            if (p_arr.length == 0) {
                // nur ein Parameter
                //p_pair = param_str.split("=");
                i = serialized.indexOf("=");
                if (i == -1) {
                    return ret_arr;
                }
                else if (i == (serialized_str.length - 1)) {
                    ret_arr.push({ name: decodeParamString(serialized_str.substring(0, i)), value: "" });
                }
                
                else {
                    ret_arr.push({ name: decodeParamString(serialized_str.substring(0, i)), value: decodeParamString(serialized_str.substring(i + 1)) });
                }
                return ret_arr;
            }
            var j;
            for (j = 0; j < p_arr.length; j++) {
                
                i = p_arr[j].indexOf("=");
                if (i == -1) {
                    
                    continue;
                }
                else if (i == (p_arr[j].length - 1)) {

                    ret_arr.push({ name: decodeParamString(p_arr[j].substring(0, i)), value: "" });
                }
                else  {

                    ret_arr.push({ name: decodeParamString(p_arr[j].substring(0, i)), value: decodeParamString(p_arr[j].substring(i + 1)) });
                }
            }
        }
        return ret_arr;
    }


    function delayed(details) {
        //alert("Call to delayed, arg: " + JSON.stringify(details));
        if (request_data === null) {
            console.log("Sorry, request data not available for " + JSON.stringify(details));
        } else {

            if (request_data.url == details.url || details.url.indexOf(request_data.url) != -1) {// post daten zu diesem request passend, urls gleich oder teilstring enthalten z.B. http://192.168.0.1/index.php und index.php sind höchstwahrscheinlich derselbe request, noch zu verbessern
                if (details.tabId > 0){ // kommt aus einem Tab
                    
                    var param_arr = getParamsFromSerialize(request_data.data); // nehme diesen request in die datenstruktur auf zum spaeteren tampering
                    var request = { form_number: -1, params: param_arr, url: details.url, method: "post", header: details.requestHeaders, type: details.type, submission: request_data.submission }; // hier url statt action

                    if (capture_mode == 1) { // Es sollen nur requests aus activem tab des aktiven windows gecaptured werden
                        chrome.tabs.query({ active: true, highlighted: true, currentWindow: true }, function (result) {
                            
                            if (result.length != 1) {
                                alert("Error: Couldnt identify active tab");
                            }
                            if (result[0].id == details.tabId) {
                                requests.push(request);
                                
                            }
                            
                        });
                    }
                    else { // aus jedem tab soll gecaptured werden
                        requests.push(request);
                    }

                    request_data = null;
                }
                else {
                    request_data = null;
                }
            }
            else {
                // Sollte nicht vorkommen?!
                alert("Sorry, no matching data available for " + JSON.stringify(details));
            }
        }
       
    }

    var extraInfo = ["requestHeaders","blocking"]; // bei "blocking" wird kein Request von getHtmlResponseFromTampered eingefangen, ohne funktioniert dies aber?!

    chrome.webRequest.onBeforeSendHeaders.addListener( //onBeforeRequest
        function (details) {
            //console.log("Call To oBSH Listener, arg: " + JSON.stringify(details));
            if (capture_mode > -1) {
                if (details.method == "POST") {
                    /********************************************************************************************************************
                    diesen Hack verbessern sobald chrome.webRequest Object post parameter unterstuetzt            
                    Problem: hier timeout damit Daten von ContentScript sicher vorher ankommen, ohne diesen timeout nicht immer der fall
                    *********************************************************************************************************************/
                    
                    window.setTimeout(function () { delayed(details); }, 5);
                }
                if (details.method == "GET") {
                    var param_arr = getParamsFromURL(details.url);
                    var url;
                    if (param_arr.length > 0) { // nur URLs mit Parametern
                        url = details.url.substring(0, details.url.indexOf("?"));
                    }
                    else {
                        url = details.url;
                    }
                    var request = { form_number: -1, params: param_arr, url: url, method: "get", header: details.requestHeaders, type: details.type };

                    if (details.tabId > 0) {  // kommt aus einem Tab
                        if (capture_mode == 1) { // Es sollen nur requests aus activem tab des aktiven windows gecaptured werden
                            chrome.tabs.query({ active: true, highlighted: true, currentWindow: true }, function (result) {
                                if (result.length != 1) {
                                    alert("Error: Couldnt identify active tab");
                                    return;
                                }
                                if (result[0].id == details.tabId) {
                                    requests.push(request);
                                }
                            });
                        }
                        else { // aus jedem tab soll gecaptured werden
                            requests.push(request);
                        }
                    }
                }
                if (blocking_mode) {
                    //console.log("Request blocked");
                    return { cancel: true };
                }
            }
        },
        { urls: ["<all_urls>"] },
        extraInfo
    );    

   
    chrome.extension.onRequest.addListener(
        // Achtung: Es kann hier vorkommen dass Chrome.webRequest Listerner vor dieser Funktion aufgerufen wird, dann kann POST request nicht eingefangen werden
        function (request, sender, sendResponse) {
            request_data = request;
            //alert("Received data Request form Content Script: "+request_data.data);
    });

    
</script>
</head>
    <body>
    </body>
</html>